--- glog-0.3.3/src/glog/logging.h.in	2013-02-01 14:20:46.000000000 +0800
+++ glog-0.3.3/src/glog/logging.h.in	2016-03-18 10:32:00.127125712 +0800
@@ -316,6 +316,11 @@
   using fLS::FLAGS_##name
 #endif
 
+DECLARE_int32(log_filenum_quota);
+
+DECLARE_string(log_split_method);
+
+
 // Set whether log messages go to stderr instead of logfiles
 DECLARE_bool(logtostderr);
 
--- glog-0.3.3/src/logging.cc	2013-02-01 14:20:46.000000000 +0800
+++ glog-0.3.3/src/logging.cc	2016-03-18 10:37:18.331126494 +0800
@@ -48,13 +48,17 @@
 #include <iostream>
 #include <stdarg.h>
 #include <stdlib.h>
+#include <dirent.h>
 #ifdef HAVE_PWD_H
 # include <pwd.h>
 #endif
 #ifdef HAVE_SYSLOG_H
 # include <syslog.h>
 #endif
+#include <algorithm>
 #include <vector>
+#include <list>
+#include <string>
 #include <errno.h>                   // for errno
 #include <sstream>
 #include "base/commandlineflags.h"        // to get the program name
@@ -170,6 +174,12 @@
                   "approx. maximum log file size (in MB). A value of 0 will "
                   "be silently overridden to 1.");
 
+GLOG_DEFINE_string(log_split_method, "day",
+                  "split log by size, day, hour");
+
+GLOG_DEFINE_int32(log_filenum_quota, 10,
+				   "max log file num in log dir");
+
 GLOG_DEFINE_bool(stop_logging_if_full_disk, false,
                  "Stop attempting to log to disk if the disk is full.");
 
@@ -351,6 +361,15 @@
 
 namespace {
 
+typedef struct filetime {
+    std::string name;
+    time_t time;
+
+    bool operator < (const struct filetime& o) const {
+        return o.time > time;
+    }
+}Filetime;
+
 // Encapsulates all file-system related state
 class LogFileObject : public base::Logger {
  public:
@@ -382,6 +401,8 @@
   // acquiring lock_.
   void FlushUnlocked();
 
+  void CheckFileNumQuota();
+
  private:
   static const uint32 kRolloverAttemptFrequency = 0x20;
 
@@ -396,6 +417,9 @@
   uint32 file_length_;
   unsigned int rollover_attempt_;
   int64 next_flush_time_;         // cycle count at which to flush log
+  std::list<Filetime> file_list_;
+  bool inited_;
+  struct ::tm tm_time_;
 
   // Actually create a logfile using the value of base_filename_ and the
   // supplied argument time_pid_string
@@ -414,7 +438,7 @@
 
   // These methods are just forwarded to by their global versions.
   static void SetLogDestination(LogSeverity severity,
-				const char* base_filename);
+          const char* base_filename);
   static void SetLogSymlink(LogSeverity severity,
                             const char* symlink_basename);
   static void AddLogSink(LogSink *destination);
@@ -446,17 +470,17 @@
   // Take a log message of a particular severity and log it to stderr
   // iff it's of a high enough severity to deserve it.
   static void MaybeLogToStderr(LogSeverity severity, const char* message,
-			       size_t len);
+          size_t len);
 
   // Take a log message of a particular severity and log it to email
   // iff it's of a high enough severity to deserve it.
   static void MaybeLogToEmail(LogSeverity severity, const char* message,
-			      size_t len);
+          size_t len);
   // Take a log message of a particular severity and log it to a file
   // iff the base filename is not "" (which means "don't log to me")
   static void MaybeLogToLogfile(LogSeverity severity,
                                 time_t timestamp,
-				const char* message, size_t len);
+                                const char* message, size_t len);
   // Take a log message of a particular severity and log it to the file
   // for that severity and also for all files with severity less than
   // this severity.
@@ -531,7 +555,7 @@
   // assume we have the log_mutex or we simply don't care
   // about it
   for (int i = min_severity; i < NUM_SEVERITIES; i++) {
-    LogDestination* log = log_destination(i);
+    LogDestination* log = log_destinations_[i];
     if (log != NULL) {
       // Flush the base fileobject_ logger directly instead of going
       // through any wrappers to reduce chance of deadlock.
@@ -620,7 +644,7 @@
 }
 
 inline void LogDestination::SetEmailLogging(LogSeverity min_severity,
-					    const char* addresses) {
+        const char* addresses) {
   assert(min_severity >= 0 && min_severity < NUM_SEVERITIES);
   // Prevent any subtle race conditions by wrapping a mutex lock around
   // all this stuff.
@@ -673,7 +697,7 @@
 }
 
 inline void LogDestination::MaybeLogToStderr(LogSeverity severity,
-					     const char* message, size_t len) {
+        const char* message, size_t len) {
   if ((severity >= FLAGS_stderrthreshold) || FLAGS_alsologtostderr) {
     ColoredWriteToStderr(severity, message, len);
 #ifdef OS_WINDOWS
@@ -712,8 +736,8 @@
 
 inline void LogDestination::MaybeLogToLogfile(LogSeverity severity,
                                               time_t timestamp,
-					      const char* message,
-					      size_t len) {
+                                              const char* message,
+                                              size_t len) {
   const bool should_flush = severity > FLAGS_logbuflevel;
   LogDestination* destination = log_destination(severity);
   destination->logger_->Write(should_flush, timestamp, message, len);
@@ -727,8 +751,12 @@
   if ( FLAGS_logtostderr ) {           // global flag: never log to file
     ColoredWriteToStderr(severity, message, len);
   } else {
-    for (int i = severity; i >= 0; --i)
-      LogDestination::MaybeLogToLogfile(i, timestamp, message, len);
+    if (severity >= 1) {
+        LogDestination::MaybeLogToLogfile(1, timestamp, message, len);
+	LogDestination::MaybeLogToLogfile(0, timestamp, message, len);
+    } else if (severity == 0) {
+        LogDestination::MaybeLogToLogfile(0, timestamp, message, len);
+    } else {}
   }
 }
 
@@ -793,7 +821,8 @@
     bytes_since_flush_(0),
     file_length_(0),
     rollover_attempt_(kRolloverAttemptFrequency-1),
-    next_flush_time_(0) {
+    next_flush_time_(0),
+    inited_(false) {
   assert(severity >= 0);
   assert(severity < NUM_SEVERITIES);
 }
@@ -858,7 +887,7 @@
   string string_filename = base_filename_+filename_extension_+
                            time_pid_string;
   const char* filename = string_filename.c_str();
-  int fd = open(filename, O_WRONLY | O_CREAT | O_EXCL, 0664);
+  int fd = open(filename, O_WRONLY | O_CREAT /* | O_EXCL */ | O_APPEND, 0664);
   if (fd == -1) return false;
 #ifdef HAVE_FCNTL
   // Mark the file close-on-exec. We don't really care if this fails
@@ -872,6 +901,10 @@
     return false;
   }
 
+  Filetime ft;
+  ft.name = string_filename;
+  file_list_.push_back(ft);
+
   // We try to create a symlink called <program_name>.<severity>,
   // which is easier to use.  (Every time we create a new logfile,
   // we destroy the old symlink and create a new one, so it always
@@ -911,6 +944,59 @@
   return true;  // Everything worked
 }
 
+void LogFileObject::CheckFileNumQuota() {
+    struct dirent *entry;
+    DIR *dp;
+
+    const vector<string> & log_dirs = GetLoggingDirectories();
+    if (log_dirs.size() < 1) return;
+
+    //fprintf(stderr, "log dir: %s\n", log_dirs[0].c_str());
+
+    // list file in log dir
+    dp = opendir(log_dirs[0].c_str());
+    if (dp == NULL) {
+        fprintf(stderr, "open log dir %s fail\n", log_dirs[0].c_str());
+        return;
+    }
+
+    file_list_.clear();
+    while ((entry = readdir(dp)) != NULL) {
+        if (DT_DIR == entry->d_type ||
+                DT_LNK == entry->d_type) {
+            continue;
+        }
+        std::string filename = std::string(entry->d_name);
+        //fprintf(stderr, "filename: %s\n", filename.c_str());
+
+        if (filename.find(symlink_basename_ + '.' + LogSeverityNames[severity_]) == 0) {			
+            std::string filepath = log_dirs[0] + "/" + filename;
+
+            struct stat fstat;
+            if (::stat(filepath.c_str(), &fstat) < 0) {
+                fprintf(stderr, "state %s fail\n", filepath.c_str());
+                closedir(dp);
+                return;
+            }
+            //fprintf(stderr, "filepath: %s\n", filepath.c_str());
+
+            Filetime file_time;
+            file_time.time = fstat.st_mtime;
+            file_time.name = filepath;
+            file_list_.push_back(file_time);
+        }
+    }
+    closedir(dp);
+
+    file_list_.sort();
+
+    while (FLAGS_log_filenum_quota > 0 && file_list_.size() >= FLAGS_log_filenum_quota) {
+       // fprintf(stderr, "delete %s\n", file_list_.front().name.c_str());
+        unlink(file_list_.front().name.c_str());
+        file_list_.pop_front();
+    }
+}
+
 void LogFileObject::Write(bool force_flush,
                           time_t timestamp,
                           const char* message,
@@ -922,14 +1008,55 @@
     return;
   }
 
-  if (static_cast<int>(file_length_ >> 20) >= MaxLogSize() ||
-      PidHasChanged()) {
+  struct ::tm tm_time;
+
+  bool is_split = false;
+  if ("day" == FLAGS_log_split_method) {
+      localtime_r(&timestamp, &tm_time);
+      if (tm_time.tm_year != tm_time_.tm_year
+              || tm_time.tm_mon != tm_time_.tm_mon
+              || tm_time.tm_mday != tm_time_.tm_mday) {
+          is_split = true;
+      }
+  } else if ("hour" == FLAGS_log_split_method) {
+      localtime_r(&timestamp, &tm_time);
+      if (tm_time.tm_year != tm_time_.tm_year
+              || tm_time.tm_mon != tm_time_.tm_mon
+              || tm_time.tm_mday != tm_time_.tm_mday
+              || tm_time.tm_hour != tm_time_.tm_hour) {
+          is_split = true;
+      }
+  } else if (static_cast<int>(file_length_ >> 20) >= MaxLogSize()) {
+      // PidHasChanged()) {
+      is_split = true;
+  }
+
+  if (is_split) {
     if (file_ != NULL) fclose(file_);
     file_ = NULL;
     file_length_ = bytes_since_flush_ = 0;
     rollover_attempt_ = kRolloverAttemptFrequency-1;
   }

+  if ((file_ == NULL) && (!inited_) && (FLAGS_log_split_method == "size")) {
+    CheckFileNumQuota();
+    const char* filename = file_list_.back().name.c_str();
+    int fd = open(filename, O_WRONLY | O_CREAT /* | O_EXCL */ | O_APPEND, 0664);
+    if (fd != -1) {
+#ifdef HAVE_FCNTL
+      // Mark the file close-on-exec. We don't really care if this fails
+      fcntl(fd, F_SETFD, FD_CLOEXEC);
+#endif
+      file_ = fopen(filename, "a+"); // Read and append a FILE*.
+      if (file_ == NULL) {      // Man, we're screwed!, try to create new log file
+        close(fd);
+      }
+      fseek(file_, 0, SEEK_END);
+      file_length_ = bytes_since_flush_ = ftell(file_);
+      inited_ = true;
+    }
+  }
+ 
   // If there's no destination file, make one before outputting
   if (file_ == NULL) {
     // Try to rollover the log file every 32 log messages.  The only time
@@ -938,21 +1065,35 @@
     if (++rollover_attempt_ != kRolloverAttemptFrequency) return;
     rollover_attempt_ = 0;
 
-    struct ::tm tm_time;
-    localtime_r(&timestamp, &tm_time);
+    if (!inited_) {
+        CheckFileNumQuota();
+        inited_ = true;
+    } else {
+        while (FLAGS_log_filenum_quota > 0 && file_list_.size() >= FLAGS_log_filenum_quota) {
+            unlink(file_list_.front().name.c_str());
+            file_list_.pop_front();
+        }
+    }
 
+	localtime_r(&timestamp, &tm_time);
     // The logfile's filename will have the date/time & pid in it
     ostringstream time_pid_stream;
     time_pid_stream.fill('0');
     time_pid_stream << 1900+tm_time.tm_year
                     << setw(2) << 1+tm_time.tm_mon
-                    << setw(2) << tm_time.tm_mday
-                    << '-'
-                    << setw(2) << tm_time.tm_hour
-                    << setw(2) << tm_time.tm_min
-                    << setw(2) << tm_time.tm_sec
-                    << '.'
-                    << GetMainThreadPid();
+                    << setw(2) << tm_time.tm_mday;
+
+    if ("hour" == FLAGS_log_split_method) {
+        time_pid_stream << setw(2) << tm_time.tm_hour;
+    } else if ("day" != FLAGS_log_split_method) {
+        time_pid_stream << '-'
+            << setw(2) << tm_time.tm_hour
+            << setw(2) << tm_time.tm_min
+            << setw(2) << tm_time.tm_sec;
+    }
+    
+    tm_time_ = tm_time;
+
     const string& time_pid_string = time_pid_stream.str();
 
     if (base_filename_selected_) {
@@ -986,9 +1127,7 @@
       // deadlock. Simply use a name like invalid-user.
       if (uidname.empty()) uidname = "invalid-user";
 
-      stripped_filename = stripped_filename+'.'+hostname+'.'
-                          +uidname+".log."
-                          +LogSeverityNames[severity_]+'.';
+      stripped_filename = stripped_filename + "." + LogSeverityNames[severity_] + ".log.";
       // We're going to (potentially) try to put logs in several different dirs
       const vector<string> & log_dirs = GetLoggingDirectories();
 
@@ -1012,7 +1151,8 @@
         return;
       }
     }
-
+    
+    /*
     // Write a header message into the log file
     ostringstream file_header_stream;
     file_header_stream.fill('0');
@@ -1034,6 +1174,7 @@
     fwrite(file_header_string.data(), 1, header_len, file_);
     file_length_ += header_len;
     bytes_since_flush_ += header_len;
+    */
   }
 
   // Write to LOG file
